package featuresdemo;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

/**
 * Created by pc on 2015/2/4.
 * 当设计不可变类时，要注意其内部的可变对象*
 */
class Name {
    private String firstName;
    private String lastName;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Name name = (Name) o;
        return new EqualsBuilder()
                .append(firstName, name.firstName)
                .append(lastName, name.lastName)
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37)
                .append(firstName)
                .append(lastName)
                .toHashCode();
    }

    public Name(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getFirstName() {
        return this.firstName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getLastName() {
        return this.lastName;
    }
}

public class ImmutableClass{
    private final Name name;

    //可变类的构造方法
//    public ImmutableClass(Name sname) {
//        this.name = sname;
//    }

    //不可变类的构造方法
    public ImmutableClass(Name sname) {
        this.name = new Name(sname.getFirstName(), sname.getLastName());
    }

    public String toString(){
        return name.getLastName() + " " + name.getFirstName();
    }


    public static void main(String[] args) {
        //final只能保证引用对象地址不变，不能保证引用对象的值不变！！
        final StringBuilder sb = new StringBuilder("Immutable");
        sb.append(" changed");
        sb.append(" changed again!");
        System.out.println(sb);

        //包含了可变field， name
        Name n = new Name("悟空", "孙");
        ImmutableClass p = new ImmutableClass(n);
        // ImmutableClass对象的name的firstName值为"悟空"
        System.out.println(p);

        // 改变ImmutableClass对象name的firstName值
        n.setFirstName("八戒");
        // ImmutableClass对象的name的firstName值被改为"八戒"
        System.out.println(p);
    }
}
